#include		"XmlParser.hpp"
#include		<iostream>

using namespace std;

XmlParser::XmlParser()
{
	_pos = 0;
	_text = "";
}
XmlParser::~XmlParser()
{
}


int			XmlParser::consumeBlanks(int & pos)
{
	char		c;
	int			ret = 0;

	c = this->_text[pos];
	this->_text;
	while (c == ' ' || c == '\t' || \
			c == '\r' || c == '\n')
	{
		++pos;
		c = this->_text[pos];
		++ret;
	}
	return (ret);
}

int			XmlParser::consumeBlanks(string & str, int & pos)
{
	char		c;
	int			ret = 0;

	c = str[pos];
	while (c == ' ' || c == '\t' || \
			c == '\r' || c == '\n')
	{
		++pos;
		c = str[pos];
		++ret;
	}
	return (ret);
}


void			XmlParser::setText(const std::string &val)
{
	this->_text = val;
	this->_pos = 0;
	return ;
}
//Don't move the pos
const std::string	XmlParser::findNextTag()
{
	int			i_tmp = this->_pos;
	int			count = 0;
	string		ret = "";

	consumeBlanks(i_tmp);
	while (count != 2 && this->_text[i_tmp])
	{
		if (count == 0 && this->_text[i_tmp] == '<')
			++count;
		else if (count == 1 && this->_text[i_tmp] != '>')
			ret += this->_text[i_tmp];
		else
			count = 2;
		++i_tmp;
	}	
	return (ret);
}

//Here move the pos (using a reference)
const std::string		XmlParser::consumeNextTag()
{
	int	&		i_tmp = this->_pos;
	int			count = 0;
	string		ret = "";

	consumeBlanks(i_tmp);
	while (count != 2 && this->_text[i_tmp])
	{
		if (count == 0 && this->_text[i_tmp] == '<')
			++count;
		else if (count == 1 && this->_text[i_tmp] != '>')
			ret += this->_text[i_tmp];
		else
			count = 2;
		++i_tmp;
	}
	return (ret);
}
const std::string		XmlParser::getCompleteLine()
{
	int	&		i_tmp = this->_pos;
	int			tmp = 0;
	int			stop = 1;
	int			count = 0;
	string		currentTag = "";
	string		endTag = "";
	string		ret = "";

	consumeBlanks(i_tmp);
	while (stop && this->_text[i_tmp])
	{
		tmp = i_tmp;
		if (count == 0 && this->_text[i_tmp] == '<')
			++count;
		else if (count == 1 && consumeBlanks(tmp) == 0 && this->_text[i_tmp] != '>')
			currentTag += this->_text[i_tmp];
		else if (count < 2)
			count = 2;
		if (count >= 2)
		{
			if (this->_text[i_tmp] == '<')
			{
				endTag = "";
				count = 3;
			}
			else 
			{
				if (count == 3 && this->_text[i_tmp] == '/')
					count = 4;
				else if (count == 4)
				{
					if (this->_text[i_tmp] != '>')
						endTag += this->_text[i_tmp];
					else
					{
						if (endTag == currentTag)
							stop = 0;
						else
						{
							endTag = "";
							count = 2;
						}
					}
				}
				else
					count = 2;
			}
		}
		ret += this->_text[i_tmp];
		++i_tmp;
	}
	if (stop == 1)
		ret = "Wrong xml stream";
	return (ret);
}
const std::string		XmlParser::getTag(std::string &completeLine)
{
	string				ret = "";
	int					i = 0, tmp = 0;
	int					count = 0, stop = 1;

	while (stop && completeLine[i])
	{
		tmp = i;
		if (count == 0 && completeLine[i] == '<')
			++count;
		else if (count == 1 && consumeBlanks(completeLine, tmp) == 0 && \
				completeLine[i] != '>')
			ret += completeLine[i];
		else if (count == 1)
			stop = 0;
		++i;
	}
	return (ret);
}

const std::string		XmlParser::getBody(std::string &completeLine)
{
	int			i = 0;
	int			tmp = 0;
	int			stop = 1;
	int			count = 0;
	int			end_pos = 0;
	string		currentTag = "";
	string		endTag = "";
	string		ret = "";

	//consumeBlanks(i);
	while (stop && completeLine[i])
	{
		tmp = i;
		if (count == 0 && completeLine[i] == '<')
			++count;
		else if (count == 1 && consumeBlanks(completeLine, tmp) == 0 && completeLine[i] != '>')
			currentTag += completeLine[i];
		else if (count == 1 && completeLine[i] == '>')
			count = 2;
		else if (count >= 2)
		{
			ret += completeLine[i];
			if (completeLine[i] == '<')
			{
				endTag = "";
				end_pos = ret.size();
				count = 3;
			}
			else 
			{
				if (count == 3 && completeLine[i] == '/')
					count = 4;
				else if (count == 4)
				{
					if (completeLine[i] != '>')
						endTag += completeLine[i];
					else
					{
						if (endTag == currentTag)
							stop = 0;
						else
						{
							endTag = "";
							end_pos = 0;
							count = 2;
						}
					}
				}
				else
					count = 2;
			}
		}
		++i;
	}
	if (end_pos > 0)
		ret.resize(end_pos - 1);
	return (ret);
}


void					XmlParser::consumeHeaderHttp()
{
	while (this->_text[this->_pos] && this->_text[this->_pos] != '<')
		++this->_pos;
	cout << "------" << this->_text[this->_pos] << "------" << endl;
	return ;
}